home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Keyboard.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  5KB  |  250 lines

  1. #include "stdafx.h"
  2.  
  3. char key[256];
  4. DWORD key_up[3], key_down[3], key_left[3], key_right[3], key_fire[3];
  5.  
  6. static LPDIRECTINPUTDEVICE2 keyboard = 0;
  7. static int key_last[256];
  8. static int key_double[256];
  9.  
  10. static void reset_keyboard()
  11. {
  12.     for (int i = 0; i < 256; i++)
  13.     {
  14.         key[i] = 0;
  15.         key_last[i] = 0;
  16.         key_double[i] = FALSE;
  17.     }
  18.  
  19. }
  20.  
  21. void init_keyboard()
  22. {
  23.     keyboard = create_input_device_keyboard();
  24.  
  25.     reset_keyboard();
  26. }
  27.  
  28. void deinit_keyboard()
  29. {
  30.     if (keyboard != 0)
  31.     {
  32.         keyboard->Unacquire();
  33.  
  34.         keyboard->Release();
  35.     }
  36. }
  37.  
  38. LPDIRECTINPUTDEVICE2 create_input_device_keyboard()
  39. {
  40.     LPDIRECTINPUTDEVICE2 keyboard;
  41.  
  42.     keyboard = create_input_device(GUID_SysKeyboard);
  43.  
  44.     if (FAILED(keyboard->SetCooperativeLevel(mainwindowhandle, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)))
  45.         error("Unable to set cooperative level for keyboard");
  46.  
  47.     if (FAILED(keyboard->SetDataFormat(&c_dfDIKeyboard)))
  48.         error("Unable to set data format to keyboard");
  49.  
  50.     DIPROPDWORD dipdw;
  51.  
  52.     dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  53.     dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  54.     dipdw.diph.dwObj = 0;
  55.     dipdw.diph.dwHow = DIPH_DEVICE;
  56.     dipdw.dwData = KEY_BUFFERSIZE;
  57.     
  58.     if (FAILED(keyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
  59.         error("Unable to set keyboard buffer size");
  60.  
  61.     return keyboard;
  62. }
  63.  
  64. void readout_keyboard()
  65. {
  66.     // Get the state of the keyboard
  67.  
  68.     if (FAILED(keyboard->GetDeviceState(sizeof(key), key)))
  69.     {
  70.         keyboard->Acquire();
  71.  
  72.         if (FAILED(keyboard->GetDeviceState(sizeof(key), key)))
  73.         {
  74.             reset_keyboard();
  75.             return;
  76.         }
  77.     }    
  78.  
  79.     // Get the state in a buffer for checking doubleclicks
  80.  
  81.     DIDEVICEOBJECTDATA dod[KEY_BUFFERSIZE];
  82.     DWORD items = KEY_BUFFERSIZE;
  83.  
  84.     if (FAILED(keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), dod, &items, 0)))
  85.     {
  86.         keyboard->Acquire();
  87.  
  88.         if (FAILED(keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), dod, &items, 0)))
  89.         {
  90.             reset_keyboard();
  91.             return;
  92.         }
  93.     }
  94.  
  95.     for (DWORD d = 0; d < items; d++)
  96.     {
  97.         // Check if this means a button is pressed
  98.         
  99.         if (dod[d].dwData & 0x80)
  100.         {
  101.             
  102.             if (dod[d].dwTimeStamp - key_last[dod[d].dwOfs] <= KEY_DCLICKTIME)
  103.             {
  104.                 // This is a double click
  105.  
  106.                 key_last[dod[d].dwOfs] = 0;
  107.                 key_double[dod[d].dwOfs] = TRUE;
  108.             }
  109.             else
  110.             {
  111.                 // It's not a double click, but remember last time this key was pressed
  112.  
  113.                 key_last[dod[d].dwOfs] = dod[d].dwTimeStamp;
  114.             }
  115.         }
  116.     }
  117. }
  118.  
  119. cKeyboard::cKeyboard(int num)
  120. {
  121.     up = key_up[num];
  122.     down = key_down[num];
  123.     left = key_left[num];
  124.     right = key_right[num];
  125.     fire = key_fire[num];
  126.     
  127.     reset();
  128. }
  129.  
  130. void cKeyboard::reset()
  131. {
  132.     key_last[up] = 0;
  133.     key_double[up] = FALSE;    
  134. }
  135.  
  136. #define pressed(x)  (key[x] & 0x80)
  137.  
  138. void cKeyboard::determine(cPlayer *p)
  139. {
  140.     // Make sure structures are up to date
  141.  
  142.     readout_keyboard();
  143.  
  144.     // Cannot do anything when not active
  145.  
  146.     if (!p->is_active())
  147.     {
  148.         reset();
  149.         return;
  150.     }
  151.         
  152.     // Check fire button
  153.     
  154.     if (pressed(fire))
  155.     {
  156.         if (pressed(up))
  157.             p->fire_up();
  158.         else if (pressed(down) && (pressed(left) || pressed(right)))
  159.             p->fire_down();
  160.         else
  161.             p->fire();
  162.     }
  163.     
  164.     // Cannot do anything more when captured
  165.     
  166.     if (p->is_captured())
  167.     {
  168.         reset();
  169.  
  170.         return;
  171.     }
  172.     
  173.     // Jetpack on double click up
  174.     
  175.     if (key_double[up])
  176.     {
  177.         p->jet_on();    
  178.  
  179.         key_double[up] = FALSE;
  180.     }
  181.     
  182.     // Do movement
  183.         
  184.     if (p->is_walking())
  185.     { 
  186.         if (pressed(left))
  187.             p->walk_left();
  188.         else if (pressed(right))
  189.             p->walk_right();
  190.         else
  191.             p->walk_h_halt();
  192.         
  193.         if (pressed(up) && !pressed(fire))
  194.             p->jump();
  195.         else if (pressed(down))
  196.             p->duck();
  197.     }
  198.     else if (p->is_ducked())
  199.     {
  200.         if (!pressed(down))
  201.             p->stand();
  202.         
  203.         if (pressed(left))
  204.             p->duck_left();
  205.         else if (pressed(right))
  206.             p->duck_right();
  207.     }
  208.     else if (p->is_jumping())
  209.     {
  210.         if (pressed(left))
  211.             p->jump_left();
  212.         else if (pressed(right))
  213.             p->jump_right();
  214.         else
  215.             p->jump_h_halt();
  216.     }
  217.     else if (p->is_jetting())
  218.     {
  219.         if (pressed(up))
  220.             p->jet_up();
  221.         else if (pressed(down))
  222.             p->jet_off();
  223.         else
  224.             p->jet_v_halt();
  225.         
  226.         if (pressed(left))
  227.             p->jet_left();
  228.         else if (pressed(right))
  229.             p->jet_right();
  230.         else
  231.             p->jet_h_halt();
  232.     }
  233.     else if (p->is_climbing())
  234.     {
  235.         if (pressed(up))
  236.             p->climb_up();
  237.         else if (pressed(down))
  238.             p->climb_down();
  239.         else
  240.             p->climb_v_halt();
  241.         
  242.         if (pressed(left))
  243.             p->climb_left();
  244.         else if (pressed(right))
  245.             p->climb_right();
  246.         else
  247.             p->climb_h_halt();
  248.     }
  249. }
  250.